//
//  LiveStreamUploadRoomViewModel.swift
//  live
//
//  Created by melvyn on 2018/8/16.
//  Copyright © 2018 NEET. All rights reserved.
//

import Foundation
import class UIKit.UIImage
import RxSwift
import RxCocoa
import Link

final class LiveStreamUploadRoomViewModel: RxViewModel {
    
    let disposeBag = DisposeBag()
    
    let title: BehaviorRelay<String> = BehaviorRelay(value: "")
    let tag: BehaviorRelay<String> = BehaviorRelay(value: "TAG")
    let metadata: BehaviorRelay<Data> = BehaviorRelay(value: Data())
    let roomID: Driver<String>
    let avatar: Driver<Thumbnail>
    let timeInterval: Observable<String>
    var shutdown: PublishSubject<Void> = PublishSubject()
    let captureDevicePosition: BehaviorRelay<AVCaptureDevice.Position> = BehaviorRelay(value: .back)
    var openLiveStream: PublishSubject<Void> = PublishSubject()
    var isEnabled: Driver<Bool> = Driver.never()
    var isStreaming: Driver<Bool> = BehaviorRelay(value: false).asDriver()
    let danmakuListViewModel: DanmakuListViewModel
    
    private var messenger: BehaviorRelay<Messenger> = BehaviorRelay(value: Messenger.init(-1))
    
    init() {
        
        let streamInfo = Observable.combineLatest(title, metadata, tag)
        
        isEnabled = streamInfo.map({
            $0.0.count > 0 && !$0.1.isEmpty && $0.2.count > 0
        })
            .asDriver(onErrorJustReturn: true)
        
        let openLiveStream = self.openLiveStream.withLatestFrom(streamInfo)
            .map({ LiveStream.MultipartForm.init(key: UUID().uuidString, tag: $0.2, title: $0.0, metadata: $0.1) })
            .flatMapLatest({
                AppManager.default.API.openLiveStream($0)
            })
            .map({ $0.value })
            .unwrap()
            .share(replay: 1, scope: .forever)
        
        openLiveStream
            .bind(to: LiveSession.default.rx.open)
            .disposed(by: disposeBag)
        
        avatar = AppManager.default.user
            .map({ ($0?.avatar, "default_avatar_64x64_") })
            .asDriver(onErrorJustReturn: (nil, "default_avatar_64x64_"))
        
        roomID = AppManager.default.user
            .map({ $0?.id.description ?? "--" })
            .asDriver(onErrorJustReturn: "--")
        
        isStreaming = openLiveStream
            .map { _ in true }
            .asDriver(onErrorJustReturn: true)
        
        timeInterval = openLiveStream.flatMapLatest { _ in
            Observable<Int>.interval(1, scheduler: MainScheduler.instance)
            }
            .map({ $0.timeDescription })
        
        let danmakus = openLiveStream
            .map({ $0.id })
            .unwrap()
            .map(Messenger.init)
            .do(onNext: { $0.open() })
            .flatMapLatest({ $0.isConnected })
            .filter({ $0 })
            .withLatestFrom(messenger)
            .flatMapLatest({ $0.comments() })
            .map({ $0.value })
            .unwrap()
        
        danmakuListViewModel = DanmakuListViewModel.init(danmakus: danmakus)
        
        shutdown.withLatestFrom(openLiveStream)
            .flatMapLatest({
                AppManager.default.API.shutdownLiveStream($0)
            })
            .map({ $0.value })
            .unwrap()
            .bind(to: LiveSession.default.rx.shutdown)
            .disposed(by: disposeBag)
    }
}
